package com.vf.cloud.rendering.server.relay.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import com.jfinal.kit.StrKit;
import com.vf.cloud.common.pool.ProssPool;
import com.vf.cloud.rendering.common.constant.Cache;
import com.vf.cloud.rendering.common.constant.SoftPath;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class StunServer implements Runnable{
	
	
	/**
	 * 0-停止 1-正在启动 2-运行中 3-停止中
	 */
	private int status = 0;
	

	@Override
	public void run() {
		status =1;
		start();
	}
	
	public void start() {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
            	String stunServerPid=ProssPool.getPid(Cache.relay.getStunPort()+"");
                if(!StrKit.isBlank(stunServerPid)) {
					ProssPool.killByPid(stunServerPid);
				}
                
                log.info(">>>正在启动 --> STUNServer:" + Cache.relay.getStunPort());
				
				if (!genSTUNServerStartBat()) {
					log.error(">>>生成启动Bat脚本失败 --> STUNServer:" + Cache.relay.getStunPort());
					return -1;
				}
				executeCmd(String.format("%s/Relay/Start_STUNServer.bat", SoftPath.path));
                return 0;
            }
        }, executor);
        future.thenAccept(e -> {
			File f=new File(String.format("%s/Relay/Start_STUNServer.bat", SoftPath.path));
			if(f.exists()) f.delete();
			status =0;
        });
	}
	
	public void stop() {
		status =3;
		if (!genStunserverStopBat()) {
			log.error("Stunserver生成停止bat文件失败，请联系管理员.");
			status =2;
			return;
		}
		int status = executeCmd(String.format("%s/Relay/Stop_STUNServer.bat", SoftPath.path));
		File f=new File(String.format("%s/Relay/Stop_STUNServer.bat", SoftPath.path));
		if (0 != status) {
			log.error("停止STUNServer失败，请联系管理员.");
			status =2;
			f.delete();
			return;
		}
		f.delete();
		log.info("STUNServer >>> 已停止运行.");
		status =0;
	}
	
	private int executeCmd(String command) {
		try {
			Runtime runtime = Runtime.getRuntime();
			Process process = runtime.exec(command);
			new Thread(new ConsoleThread(new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))))
					.start();
			return process.waitFor();
		} catch (InterruptedException | IOException e) {
		}
		return -1;
	}

	class ConsoleThread implements Runnable {
		private BufferedReader bfr = null;

		public ConsoleThread(BufferedReader bfr) {
			this.bfr = bfr;
		}

		@Override
		public void run() {
			String line = null;
			try {
				while ((line = bfr.readLine()) != null) {
					log.info(line);
					if(line.contains("Listening")) {
						status =2;
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public boolean genSTUNServerStartBat() {
		BufferedWriter out = null;
		try {
			try {
				File f = new File(String.format("%s/Relay/Start_STUNServer.bat", SoftPath.path));
				if (f.exists()) {
					f.delete();
				}
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true)));
				out.write("@echo off \r\n");
				out.write(String.format("%s \r\n", SoftPath.path.substring(0, 2)));
				out.write(String.format("cd %s/Relay \r\n", SoftPath.path));
				out.write(String.format("stunserver.exe 0.0.0.0:%s \r\n", Cache.relay.getStunPort()));
				out.write("echo \"startStunserver1999\" \r\n");
				out.write("exit");
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
			}
		}
		return false;
	}
	
	
	public boolean genStunserverStopBat() {
		BufferedWriter out = null;
		try {
			try {
				File f = new File(String.format("%s/Relay/Stop_STUNServer.bat", SoftPath.path));
				if (f.exists()) {
					f.delete();
				}
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true)));

				out.write("@echo off \r\n");
				out.write(String.format("%s \r\n", SoftPath.path.substring(0, 2)));
				out.write(String.format("cd %s/Relay \r\n", SoftPath.path));
				out.write("tasklist | findstr /i \"stunserver.exe\" \r\n");
				out.write("@echo \"stunserver is running, stopping...\"  \r\n");
				out.write("TASKKILL /F /IM stunserver.exe /T \r\n");
				out.write("echo \"stopStunserver1999\" \r\n");
				out.write("exit");
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
			}
		}
		return false;
	}

	public int getStatus() {
		return status;
	}

	
	

}
